#!/usr/bin/env perl
use warnings;
use strict;

#
# Builds a version of the probe set answers file in which each rating
# has a category for blending. The category is based on a given "measure"
# file and bins given on the command line.
#
# First argument: a measure file, which contais double-precision
# numbers (as strings), one on each line. Each line corresponds to a movie.
# Remaining arguments: bin boundaries b_1 b_2 ... b_n
#
# If the measure of a movie is in the range [b_{k-1}, b_{k}), it is placed in
# category k. Here, we define b_0 = -infinity, b_{n+1} = +infinity. So, if
# you pass n bins, you will get n+1 categories.
#
# Takes a probe_answers file on stdin (like the one in netflix/data).
# Produces the categorized file on stdout.
#

my $argc = scalar(@ARGV);
$argc > 1 or die "see comments for usage";
my ($measure_file, @bins) = @ARGV;
-e$measure_file or die "measure file $measure_file not found";
my $nbins= scalar(@bins);

# Keep track of how many movies and ratings we put in each bin.
my %movies, my %ratings;

# Load measures file; it's not very big.
open(my $fh, "<$measure_file");
my @measures = <$fh>;
close($fh);

# Read probe input and write output as we go.
my $category;
while (<STDIN>) {
  chomp;
  if (/(\d+):/) {
    my $movie_id = int($1);

    # Keep the movie line.
    print;

    # This is a movie. Look up its measure.
    my $measure = $measures[$movie_id - 1];

    # Find its category (bin).
    for ($category = 1; $category <= $nbins
      && $measure >= $bins[$category - 1]; ++$category) {
      # all work done in loop
    }

    $movies{$category}++;
  } else {
    defined($category) or die "expected probe answers to start with movie id";
    /(\d+,\d+,).*/ or die "unexpected rating line format ($_)";
    print $1, $category;

    $ratings{$category}++;
  }
  print "\n";
}

for ($category = 1; $category <= $nbins + 1; ++$category) {
  my $movie_count = 0;
  my $rating_count = 0;
  my $bin_name = '>';
  if (defined($movies{$category})) { $movie_count = $movies{$category}; }
  if (defined($ratings{$category})) { $rating_count = $ratings{$category}; }
  if ($category <= $nbins) { $bin_name = "<$bins[$category-1]"; }
  print STDERR "category $category ($bin_name): $movie_count movies\t$rating_count ratings\n";
}

# Copyright (c) 2009 John Lees-Miller
# 
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
# 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

